﻿using System;
using System.Text;
using System.Collections.Generic;
using Checkers.View.ConsoleView;
using Checkers.Common;

namespace Checkers.Game
{
    /// <summary>
    /// This class repersnts the session of the game
    /// </summary>
    public class ConsoleFlow
    {
        // Members
        private CheckersGame m_Game;

        public ConsoleFlow()
        {
        }

        /// <summary>
        /// Starts a new checkers game series
        /// </summary>
        public void Start()
        {
            bool userExited = false;

            // Welcome the user
            ConsoleDisplay.ShowWelcome();

            // Init the game
            int boardSize = ConsoleDisplay.GetBoardSize(CheckersGame.K_LegitGameSizes);
            if (boardSize == ConsoleDisplay.sk_NumericExitCode)
            {
                // If the user exited
                userExited = true;
            }
            else
            {
                // Set the game type
                eGameType gameType = ConsoleDisplay.GetGameType();

                // Init the game
                m_Game = new CheckersGame(boardSize, gameType);

                // Start a new game until the user wishes to quit
                while (!userExited)
                {
                    // Play a game
                    m_Game.StartSingleGame();
                    playSingleGame();

                    // Show mid summary
                    ConsoleDisplay.ShowMidSummary(m_Game.GameData, m_Game.LastMove);

                    // Ask to resume
                    userExited = ConsoleDisplay.GetPlayAgain();
                }

                // Show games summary
                ConsoleDisplay.ShowTotalSummary(m_Game.GameData);
            }

            // End of all games
            ConsoleDisplay.ShowGoodbye();
        }

        /// <summary>
        /// Plays a single checkers game
        /// </summary>
        private void playSingleGame()
        {
            // Show start state
            ConsoleDisplay.ShowGamePlay(m_Game.GameData);
            GameMove currentMove = null;
            GamePlayer lastPlayer = null;

            // Get moves and play untill game is over or the user forfeits
            do
            {
                // Get the next move - if its a human, get it from the input, if its a computer get it from the engine
                lastPlayer = m_Game.GameData.CurrentPlayer;
                currentMove = lastPlayer.PlayerType == ePlayerType.Human ?
                    ConsoleDisplay.GetMove(m_Game.GameData.CurrentPlayer) : m_Game.GetComputerMove(m_Game.GameData.CurrentPlayer);

                if (currentMove == null)
                {
                    // The user forfeits
                    m_Game.ForfeitGame();
                }
                else if (m_Game.IsLocInOffTheBoard(currentMove.DestCellLocation) ||
                        m_Game.IsLocInOffTheBoard(currentMove.SourceCellLoc))
                {
                    // The move is not within the board's bounds
                    ConsoleDisplay.ShowMoveRangeError();
                }
                else if (!m_Game.RunASingleTurn(currentMove))
                {
                    // The move is illegal
                    ConsoleDisplay.ShowMoveIllegalError();
                }
                else
                {
                    // The move was made, switch turns and show the new board
                    ConsoleDisplay.ShowGamePlay(m_Game.GameData);
                    ConsoleDisplay.ShowLastMove(lastPlayer, m_Game.LastMove, m_Game.LastBurntMove);
                }
            }
            while (m_Game.GameData.GameStatus == eGameStatus.Active);
        }
    }
}
